package com.starhub.application.collection.common;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.starhub.application.collection.mapper.MetaDataMapper;
import com.starhub.application.collection.constant.DatabaseConstant;
import com.starhub.utils.Util;

import lombok.extern.slf4j.Slf4j;

/**
 * 数据库表创建工具类
 * @version: V1.0
 * @author: liuhf
 * @time 2025-06-06
 */
@Slf4j
@Component
public class TableCreationHelper {

    @Autowired
    private MetaDataMapper metaDataMapper;

    /**
     * 获取表名
     * @param tableName 表名
     * @return 表名
     */
    public static String getTableName(String tableName) {
        return DatabaseConstant.TABLE_PREFIX + tableName;
    }
    
    /**
     * 创建基础元数据表
     * @param realTableName 表名
     * @return 是否创建成功
     */
    public boolean createBaseMetaTable(String name, String realTableName) {
        String tableName = getTableName(realTableName);
        try {
            String tableComment = Util.isEmpty(name) ? DatabaseConstant.DEFAULT_TABLENAME : name;
            int result = metaDataMapper.createMetaTable(tableName, tableComment);
            
            log.info("Created meta table: {}", tableName);
            return true;
        } catch (Exception e) {
            log.error("Failed to create meta table: {}", tableName, e);
            throw new RuntimeException("Failed to create meta table: " + e.getMessage(), e);
        }
    }

    /**
     * 创建表字段
     * @param realTableName 表名
     * @param fieldName 字段名
     * @param fieldType 字段类型
     * @param length 长度
     * @param precision 精度
     * @param scale 小数位
     * @param isNullable 是否可为空
     * @param defaultValue 默认值
     * @param comment 注释
     * @return 是否创建成功
     */
    public boolean addTableField(String realTableName, String fieldName, String fieldType, 
            Integer length, Integer precision, Integer scale, 
            boolean isNullable, String defaultValue, String comment) {
        String tableName = getTableName(realTableName);
        try {
            int result = metaDataMapper.addTableField(tableName, fieldName, fieldType,
                    length, precision, scale, isNullable, defaultValue, comment);
            
            log.info("Added field {} to table {}", fieldName, tableName);
            return true;
        } catch (Exception e) {
            log.error("Failed to add field {} to table {}", fieldName, tableName, e);
            throw new RuntimeException("Failed to add field: " + e.getMessage(), e);
        }
    }

    /**
     * 创建表索引
     * @param realTableName 表名
     * @param indexName 索引名
     * @param fieldNames 字段名列表
     * @param indexType 索引类型
     * @return 是否创建成功
     */
    public boolean createIndex(String realTableName, String indexName, String[] fieldNames, String indexType) {
        String tableName = getTableName(realTableName);
        try {
            String fieldNamesStr = String.join(",", fieldNames);
            int result = metaDataMapper.createIndex(tableName, indexName, fieldNamesStr, indexType);
            
            log.info("Created index {} on table {}", indexName, tableName);
            return true;
        } catch (Exception e) {
            log.error("Failed to create index {} on table {}", indexName, tableName, e);
            throw new RuntimeException("Failed to create index: " + e.getMessage(), e);
        }
    }

    /**
     * 检查表是否存在
     * @param realTableName 表名
     * @return 是否存在
     */
    public boolean isTableExists(String realTableName) {
        String tableName = getTableName(realTableName);
        try {
            int count = metaDataMapper.isTableExists(tableName);
            return count > 0;
        } catch (Exception e) {
            log.error("Failed to check if table exists: {}", tableName, e);
            throw new RuntimeException("Failed to check if table exists: " + e.getMessage(), e);
        }
    }

    /**
     * 创建主数据和元数据关联表
     * @return 是否创建成功
     */
    public boolean createDataRelationTable() {
        String tableName = DatabaseConstant.TABLE_PREFIX + "data_relation";
        try {
            // 检查表是否已存在
            if (isTableExists(tableName)) {
                log.warn("Table already exists: {}", tableName);
                return false;
            }

            // 创建关联表
            int result = metaDataMapper.createMetaTable(tableName, "主数据和元数据关联表");
            if (result <= 0) {
                return false;
            }

            // 添加字段
            addTableField(tableName, "main_data_id", "VARCHAR", 64, null, null, false, null, "主数据ID");
            addTableField(tableName, "main_collection_id", "BIGINT", null, null, null, false, null, "主数据表ID");
            addTableField(tableName, "main_base_id", "BIGINT", null, null, null, false, null, "主数据库ID");
            addTableField(tableName, "meta_data_id", "VARCHAR", 64, null, null, false, null, "元数据ID");
            addTableField(tableName, "meta_collection_id", "BIGINT", null, null, null, false, null, "元数据表ID");
            addTableField(tableName, "meta_base_id", "BIGINT", null, null, null, false, null, "元数据库ID");
            addTableField(tableName, "create_time", "DATETIME", null, null, null, false, "NOW()", "创建时间");
            addTableField(tableName, "update_time", "DATETIME", null, null, null, false, "NOW()", "更新时间");
            addTableField(tableName, "delete_type", "INT", null, null, null, false, "0", "是否删除 0-否 1-是");

            // 创建索引
            // 主键索引 - 使用主数据ID和元数据ID的组合作为主键
            createIndex(tableName, "PRIMARY", new String[]{"main_data_id", "meta_data_id"}, "PRIMARY KEY");
            
            // 为了支持按主数据ID或元数据ID单独查询的场景
            createIndex(tableName, "idx_main_data_id", new String[]{"main_data_id", "delete_type"}, "INDEX");
            createIndex(tableName, "idx_meta_data_id", new String[]{"meta_data_id", "delete_type"}, "INDEX");
            
            // 为了支持按表ID查询的场景
            createIndex(tableName, "idx_main_collection", new String[]{"main_collection_id", "main_base_id", "delete_type"}, "INDEX");
            createIndex(tableName, "idx_meta_collection", new String[]{"meta_collection_id", "meta_base_id", "delete_type"}, "INDEX");

            log.info("Created data relation table: {}", tableName);
            return true;
        } catch (Exception e) {
            log.error("Failed to create data relation table: {}", tableName, e);
            throw new RuntimeException("Failed to create data relation table: " + e.getMessage(), e);
        }
    }
} 